home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 2
/
United Public Domain Gold 2.iso
/
utilities
/
pu219.dms
/
pu219.adf
/
SOURCES
/
Bugs.mod
next >
Wrap
Text File
|
1992-07-16
|
7KB
|
261 lines
(**************************************************************************
** **
** ##### ## ## ##### ##### written by: **
** ## ## ## ## ## ## Robert Brandner **
** ##### ## ## ## ### #### Schillerstr. 3 **
** ## ## ## ## ## ## ## A-8280 Fürstenfeld **
** ##### ##### ##### ##### AUSTRIA/EUROPE **
** **
** This program is written in Modula-II using the compiler M2Amiga V3.3d **
** ** **
**************************************************************************)
MODULE Bugs;
IMPORT Intuition;
FROM Graphics IMPORT
RastPortPtr,SetAPen,RectFill,ReadPixel,VBeamPos;
FROM SYSTEM IMPORT
ADDRESS,ADR,INLINE;
FROM Exec IMPORT
AllocMem,FreeMem,MemReqs,MemReqSet,CopyMem,Byte,
SetTaskPri,FindTask,TaskPtr;
FROM RandomNumber IMPORT
RND,PutSeed;
FROM Hardware IMPORT
ciaa,CiaaPraFlags,CiaaPraFlagSet;
CONST STARTBUGS=10; (* Anzahl der Bugs am Anfang *)
DEATH=-20;
SATIATED=1000;
ADULT=800;
NOMOVE=0;
VERYOLD=ADULT*3;
ONEBITE=40;
TPRI=0; (* Taskpriorität *)
TYPE
BugPtr=POINTER TO Bug;
Bug=RECORD
x,y,richt,alter,energie : INTEGER;
gen : ARRAY[0..5] OF INTEGER;
p : ARRAY[0..5] OF LONGINT;
next : BugPtr;
(* folgende Zeile dient dazu, das Programm so richtig gemein zu machen *)
(* speicherfress:ARRAY[0..GEMEIN] OF CHAR *);
END;
VAR
IntBase : Intuition.IntuitionBasePtr;
rp : RastPortPtr;
buglist,newbug : BugPtr;
dx,dy : POINTER TO ARRAY[0..5] OF INTEGER;
i,xmax,ymax : INTEGER;
thisTask : TaskPtr;
old : Byte;
(* $R- Bereichskontrolle *)
(* $S- Stacküberlauf *)
(* $V- Über-/Unterlauf *)
PROCEDURE AllocBug():BugPtr; (* Speicher für neuen Bug *)
BEGIN
RETURN AllocMem(SIZE(Bug),MemReqSet{public,memClear});
END AllocBug;
PROCEDURE InitBug(b:BugPtr);
VAR
i:INTEGER;
BEGIN
WITH b^ DO
x:=1+3*RND(xmax/3);
y:=1+3*RND(ymax/3);
richt:=0;
alter:=0;
energie:=40;
FOR i:=0 TO 5 DO gen[i]:=5 END;
p[0]:=gen[0];
FOR i:=1 TO 5 DO p[i]:=p[i-1]+gen[i] END;
next:=NIL;
END;
END InitBug;
PROCEDURE AppendBug(VAR bl,b:BugPtr); (* Bug an Bug Liste anfügen *)
VAR
help:BugPtr;
BEGIN
IF bl=NIL THEN
bl:=b
ELSE
help:=bl;
WHILE help^.next#NIL DO help:=help^.next END;
help^.next:=b;
END;
END AppendBug;
PROCEDURE KillBug(VAR prev,bl:BugPtr);
VAR
help:BugPtr;
BEGIN
help:=bl;
IF bl=buglist THEN (* Ersten Bug in Liste löschen *)
buglist:=buglist^.next;
prev:=buglist;
bl:=buglist;
ELSE (* Bugs in Liste löschen *)
bl:=bl^.next;
prev^.next:=bl;
END;
FreeMem(help,SIZE(Bug)); (* Speicher freigeben. *)
END KillBug;
PROCEDURE SplitBug(VAR bl,b:BugPtr);
VAR
new:BugPtr;
zufall,i:INTEGER;
BEGIN
new:=AllocBug();
IF new=NIL THEN RETURN END; (* kein Speicher mehr *)
b^.energie:=b^.energie/2; (* Vaterenergie halbieren *)
b^.alter:=0;
CopyMem(b,new,SIZE(Bug)); (* Vaterwerte kopieren *)
WITH new^ DO
zufall:=RND(6); (* Mutierendes Gen bestimmen *)
gen[zufall]:=gen[zufall]+1; (* Mutation *)
p[0]:=gen[0];
FOR i:=1 TO 5 DO p[i]:=p[i-1]+gen[i] END;
next:=NIL;
END;
AppendBug(bl,new);
WITH b^ DO
zufall:=RND(6); (* Mutierendes Gen bestimmen *)
gen[zufall]:=gen[zufall]-1; (* Mutation *)
IF gen[zufall]<0 THEN gen[zufall]:=0 END;
p[0]:=gen[0];
FOR i:=1 TO 5 DO p[i]:=p[i-1]+gen[i] END;
END;
END SplitBug;
PROCEDURE DrawBug(x,y,c:INTEGER);
BEGIN
IF (x<xmax) AND (y<ymax) THEN
SetAPen(rp,c);
RectFill(rp,x-1,y-1,x+1,y+1);
END
END DrawBug;
PROCEDURE MoveBugs(bl:BugPtr);
VAR
nricht,zufall,xo,yo,col:INTEGER;
ok:BOOLEAN;
prev:BugPtr;
BEGIN
prev:=bl;
WHILE bl#NIL DO
xo:=bl^.x; yo:=bl^.y;
IF (bl^.energie<=DEATH) OR (* verhungert ..REQUIESCAT.. *)
(bl^.alter>VERYOLD) THEN (* zu alt. ...IN.PACE.... *)
DrawBug(xo,yo,0);
KillBug(prev,bl);
ELSE
DEC(bl^.energie);
INC(bl^.alter);
IF bl^.energie>NOMOVE THEN (* genug Energie für Bewegung *)
WITH bl^ DO
DEC(energie);
INC(alter);
zufall:=RND(p[5]+1);
nricht:=-1; ok:=FALSE;
REPEAT
INC(nricht);
UNTIL zufall<=p[nricht];
richt:=(richt+nricht) MOD 6; (* neue Orientierung *)
xo:=x;yo:=y;
x:=x+dx^[richt]; (* neue Position *)
y:=y+dy^[richt]; (* neue Position *)
IF x<1 THEN x:=1 END;
IF x>xmax THEN x:=xmax END;
IF y<1 THEN y:=1 END;
IF y>ymax THEN y:=ymax END;
col:=ReadPixel(rp,x,y);
IF ODD(col) THEN
INC(energie,ONEBITE);
END;
DrawBug(xo,yo,0);
DrawBug(x,y,2);
END; (* WITH *)
IF (bl^.alter>=ADULT) AND (bl^.energie>=SATIATED) THEN
SplitBug(buglist,bl); (* Fortpflanzung durch Teilung *)
END;
END; (* IF energie>NOMOVE *)
prev:=bl; (* Zeiger auf Vorgänger *)
bl:=bl^.next; (* in Liste weitergehen *)
END;
END;
END MoveBugs;
PROCEDURE RemoveBugs(VAR bl:BugPtr); (* Speicher wieder freigeben *)
VAR
help:BugPtr;
BEGIN
WHILE bl#NIL DO
help:=bl^.next;
FreeMem(bl,SIZE(Bug));
bl:=help;
END;
END RemoveBugs;
PROCEDURE dxData; (* $E- *)
BEGIN
INLINE(0,2,2,0,-2,-2);
END dxData;
PROCEDURE dyData; (* $E- *)
BEGIN
INLINE(2,1,-1,-2,-1,1);
END dyData;
BEGIN (* Bugs *)
thisTask:=FindTask(NIL);
old:=SetTaskPri(thisTask,TPRI); (* Taskpriorität niedrig machen *)
PutSeed(VBeamPos()); (* Zufall vom Videostrahl abhängig *)
dx:=ADR(dxData);
dy:=ADR(dyData);
IntBase:=ADR(Intuition); (* Adresse der IntuitionBase *)
xmax:=IntBase^.activeScreen^.width-4;
ymax:=IntBase^.firstScreen^.height-4;
FOR i:=1 TO STARTBUGS DO (* STARTBUGS Bugs machen *)
newbug:=AllocBug();
IF newbug#NIL THEN
InitBug(newbug);
AppendBug(buglist,newbug);
END;
END;
LOOP
rp:=ADR(IntBase^.activeScreen^.rastPort); (* immer im aktiven Screen! *)
xmax:=IntBase^.activeScreen^.width-2;
ymax:=IntBase^.firstScreen^.height-2;
MoveBugs(buglist);
IF (buglist=NIL) OR NOT (gamePort1 IN ciaa.pra) THEN EXIT END;
END;
RemoveBugs(buglist);
Intuition.DisplayBeep(NIL); (*** Test ***)
END Bugs.